/*
 * atmelLibFunc.c
 *
 *  Created on: 11.09.2011
 *      Author: Erik Wagner
 */

#include "stdlib.h"
#include "stdio.h"
#include "atmelLib.h"

#define ROWS 16 //Anzahl der Zeilen des Displays --> 8 LEDs pro Zeile
static unsigned char stateLED[ROWS]; //Array für ein 8 x 16 Display

/*
 * Gibt die aktuell eingestellten Werte auf dem Display aus.
 *
 * Pins (PORTB):
 * 0: Clock 1. Reihe
 * 1: Latch 1. Reihe
 * 2: Daten1 1. Reihe
 * 3: Daten2 1. Reihe
 * 4: Clock 2. Reihe
 * 5: Latch 2. Reihe
 */
void refreshDisplay() {
	char zeile = 1;
	for (int bit = 1; bit < 256; bit = bit << 1, ++zeile) {
		unsigned char byte1 = 0;
		unsigned char byte2 = 0;
		for (int row = 0; row < 8; ++row) {
			if ((stateLED[row] & bit) != 0) {
				byte1 |= twoPot(row);
			}
		}
		for (int row = 8; row < 16; ++row) {
			if ((stateLED[row] & bit) != 0) {
				byte2 |= twoPot(row - 8);
			}
		}
		for (int bitMask = 1; bitMask < 256; bitMask = bitMask << 1) {
			if ((bitMask & byte1) != 0) {
				//PORTB |= 4; //Datenpin 1
			}
			if ((bitMask & byte2) != 0) {
				//PORTB |= 8; //Datenpin 2
			}
			//PORTB |= 1; //Clockpin 1. Reihe
			//PORTB = 0; //alles aus
		}
		//PORTB |= 2; //Latchpin 1. Reihe
		//PORTB |= 16; //Clockpin 2. Reihe
		//PORTB = 0; //alles aus
	}
	//PORTB |= 32; //Latchpin 2. Reihe
	//PORTB = 0; //alles aus
}

/*
 * Zeigt die aktuellen LED-Einstellungen in der Konsole an
 */
void showDisplay() {
	printf("\n");
	for (char var = 0; var < ROWS; ++var) {
		printf("\n");
		printbin(stateLED[var]);
	}
	printf("\n");
}

/*
 * Setzt den Status der LED bei (Reihe, Spalte) auf (state)
 *
 * state = 0 --> off
 * state != 0 --> on
 */
void setLED(char row, char column, char state) {
	if (state == 0) {
		stateLED[row] = ~stateLED[row];
		stateLED[row] |= twoPot(column);
		stateLED[row] = ~stateLED[row];
	} else {
		stateLED[row] |= twoPot(column);
	}
}

/*
 * Schaltet die LED an
 */
void onLED(char row, char column) {
	setLED(row, column, 1);
}

/*
 * Schaltet die LED aus
 */
void offLED(char row, char column) {
	setLED(row, column, 0);
}

/*
 * Schaltet alle LEDs dem übergebenen Array entsprechend an bzw. aus
 */
void setAllLED(unsigned char states[ROWS]) {
	for (char x = 0; x < ROWS; ++x) {
		stateLED[x] = states[x];
	}
}

/*
 * Schaltet eine horizontale Linie an LEDs an
 */
void onHorizontalLine(char row, char startColumn, char length) {
	for (char column = startColumn;
			(column < 8 || column < startColumn + length); ++column) {
		onLED(row, column);
	}
}

/*
 * Schaltet eine vertikale Linie an LEDs an
 */
void onVerticallLine(char startRow, char column, char length) {
	for (char row = startRow; (row < ROWS || row < startRow + length); ++row) {
		onLED(row, column);
	}
}

/*
 * Schaltet eine diagonale Linie an LEDs an
 */
void onDiagonalLine(char startRow, char startColumn, char length) {
	for (char row = startRow, column = startColumn;
			(row < ROWS || row < startRow + length)
					|| (column < 8 || column < startColumn + length);
			++row, ++column) {
		onLED(row, column);
	}
}

/*
 * Gibt 2^[num] zurück, wobei [num] die übergebene Zahl ist
 */
char twoPot(char num) {
	return 1 << num;
}

/*
 * Gibt eine Zahl als binär Code in der Konsole aus (Einer-BIT zuerst)
 */
void printbin(unsigned char byte) {
	for (char i = 0; i < 8; i++)
		if ((byte >> (i)) & 0x0001 == 1) {
			printf("x");
		} else {
			printf("-");
		}
	//printf("%u", (byte >> (i)) & 0x0001);
}
